/* Orbas:
 *     A open source CORBA Specification implementation from Huihoo.
 *
 * Copyright 2002-2003 Huihoo.org, Inc. All Right Reserved.
 *
 * This software is licensed under LGPL license.
 * See terms of license at gnu.org.
 *
 * For more information, visit:
 *
 * http://www.huihoo.org/orbas
 */

package org.huihoo.orbas.orb.typecode;

/**
 * <p>Description: </p>
 * TypeCode for struct.
 * <p>Copyright (c) 2002,2003</p>
 * <p>Company: <a href="http://www.huihoo.org/">huihoo.org</a></p>
 * @author <a href="http://www.huihoo.org/~mep">mep(mep@huihoo.com)</a>
 * @see <a href="http://www.huihoo.org/orbas">http://www.huihoo.org/orbas</a>
 * @version 1.0
 */

import org.omg.CORBA.StructMember;

public class TypeCodeStruct extends TypeCodeBase {

	String id;
	String name;
	StructMember[] members;

	public TypeCodeStruct(String id, String name, StructMember[] members) {
		this.id = id;
		this.name = name;
		this.members = members;
	}

	public boolean equal(org.omg.CORBA.TypeCode tc) {
		if (tc.kind() != org.omg.CORBA.TCKind.tk_struct)
			return false;

		try {
			if (id == tc.id()) {
				return true;
			}

			TypeCodeStruct tc1 = (TypeCodeStruct) tc;

			if (name != tc1.name()) {
				return false;
			}

			if ((members == null) && (tc1.member_count() == 0)) {
				return true;
			}

			for (int i = 0; i < members.length; ++i) {
				if (!(members[i].name == null || members[i].name.length() == 0
						|| tc1.members[i].name == null
						|| tc1.members[i].name.length() == 0 || members[i].name
							.equals(tc1.members[i].name))
						|| !members[i].type.equal(tc1.members[i].type)) {
					return false;
				}
			}

			return true;
		} catch (org.omg.CORBA.TypeCodePackage.BadKind ex) {
			return false;
		}
	}

	public org.omg.CORBA.TypeCode get_compact_typecode() {
		if (members == null) {
			return new TypeCodeStruct(id, null, null);
		}

		StructMember[] ret = (org.omg.CORBA.StructMember[]) members.clone();

		for (int i = 0; i < members.length; ++i) {
			ret[i].name = null;
			ret[i].type = members[i].type.get_compact_typecode();
		}

		return new TypeCodeStruct(id, null, ret);
	}

	public org.omg.CORBA.TCKind kind() {
		return org.omg.CORBA.TCKind.tk_struct;
	}

	public java.lang.String id() throws org.omg.CORBA.TypeCodePackage.BadKind {
		return id;
	}

	public java.lang.String name() throws org.omg.CORBA.TypeCodePackage.BadKind {
		return name;
	}

	public int member_count() throws org.omg.CORBA.TypeCodePackage.BadKind {
		if (members == null) {
			return 0;
		}

		return members.length;
	}

	public java.lang.String member_name(int index)
			throws org.omg.CORBA.TypeCodePackage.BadKind,
			org.omg.CORBA.TypeCodePackage.Bounds {

		if (members == null) {
			throw new org.omg.CORBA.TypeCodePackage.Bounds();
		}

		if (index >= members.length || index < 0)
			throw new org.omg.CORBA.TypeCodePackage.Bounds();

		return (members[index].name == null) ? "" : members[index].name;
	}

	public org.omg.CORBA.TypeCode member_type(int index)
			throws org.omg.CORBA.TypeCodePackage.BadKind,
			org.omg.CORBA.TypeCodePackage.Bounds {

		if (members == null) {
			throw new org.omg.CORBA.TypeCodePackage.Bounds();
		}

		if (index >= members.length || index < 0)
			throw new org.omg.CORBA.TypeCodePackage.Bounds();

		if (members[index].type instanceof TypeCodeRecursive)
			throw new org.omg.CORBA.BAD_TYPECODE(
					"Attempt to access incomplete typecode", 0,
					org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);

		return members[index].type;
	}

	public org.omg.CORBA.Any member_label(int index)
			throws org.omg.CORBA.TypeCodePackage.BadKind,
			org.omg.CORBA.TypeCodePackage.Bounds {
		throw new org.omg.CORBA.TypeCodePackage.BadKind();
	}

	public org.omg.CORBA.TypeCode discriminator_type()
			throws org.omg.CORBA.TypeCodePackage.BadKind {
		throw new org.omg.CORBA.TypeCodePackage.BadKind();
	}

	public int default_index() throws org.omg.CORBA.TypeCodePackage.BadKind {
		throw new org.omg.CORBA.TypeCodePackage.BadKind();
	}

	public int length() throws org.omg.CORBA.TypeCodePackage.BadKind {
		throw new org.omg.CORBA.TypeCodePackage.BadKind();
	}

	public org.omg.CORBA.TypeCode content_type()
			throws org.omg.CORBA.TypeCodePackage.BadKind {
		throw new org.omg.CORBA.TypeCodePackage.BadKind();
	}

	public short fixed_digits() throws org.omg.CORBA.TypeCodePackage.BadKind {
		throw new org.omg.CORBA.TypeCodePackage.BadKind();
	}

	public short fixed_scale() throws org.omg.CORBA.TypeCodePackage.BadKind {
		throw new org.omg.CORBA.TypeCodePackage.BadKind();
	}

	public short member_visibility(int index)
			throws org.omg.CORBA.TypeCodePackage.BadKind,
			org.omg.CORBA.TypeCodePackage.Bounds {
		throw new org.omg.CORBA.TypeCodePackage.BadKind();
	}

	public short type_modifier() throws org.omg.CORBA.TypeCodePackage.BadKind {
		throw new org.omg.CORBA.TypeCodePackage.BadKind();
	}

	public org.omg.CORBA.TypeCode concrete_base_type()
			throws org.omg.CORBA.TypeCodePackage.BadKind {
		throw new org.omg.CORBA.TypeCodePackage.BadKind();
	}
}
